Update Many
Migration
- Cần tạo update many cho bảng khác cần đổi tên function, schema và public.
Ví dụ:
- Tên function
public.update_many_school_names=>lms.update_many_chapters - Các schema liên quan
public.school_name=>lms.chapter
'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
// Dùng queryInterface.sequelize.query để chạy lệnh SQL thô (raw SQL)
await queryInterface.sequelize.query(`
CREATE OR REPLACE FUNCTION public.update_many_school_names(payload jsonb)
RETURNS SETOF public.school_name AS $$
DECLARE
update_cols text;
sql_query text;
BEGIN
-- 1. Validation cơ bản
IF jsonb_typeof(payload) != 'array' OR jsonb_array_length(payload) = 0 THEN
RAISE EXCEPTION 'Lỗi định dạng: Payload phải là một mảng JSON không rỗng.';
END IF;
-- 2. Đảm bảo mọi object đều có id
IF EXISTS (
SELECT 1
FROM jsonb_array_elements(payload) AS elem
WHERE NOT (elem ? 'id')
OR (elem->>'id') IS NULL
) THEN
RAISE EXCEPTION 'Lỗi thiếu Key: Mọi object trong mảng bắt buộc phải truyền "id".';
END IF;
-- 3. Tự động sinh mệnh đề SET từ key của object đầu tiên
SELECT string_agg(format('%1$I = r.%1$I', key), ', ')
INTO update_cols
FROM jsonb_object_keys(payload->0) AS key
WHERE key != 'id';
IF update_cols IS NULL OR update_cols = '' THEN
RAISE EXCEPTION 'Lỗi Payload: Không có trường dữ liệu nào cần cập nhật ngoài id.';
END IF;
-- 4. Build câu lệnh UPDATE (Fix cứng tên bảng ở đây)
sql_query := format(
'UPDATE public.school_name AS t
SET %1$s
FROM jsonb_populate_recordset(null::public.school_name, $1) AS r
WHERE t.id = r.id
RETURNING t.*',
update_cols
);
-- 5. Thực thi và trả thẳng kết quả về cho GraphQL
RETURN QUERY EXECUTE sql_query USING payload;
EXCEPTION
WHEN OTHERS THEN
RAISE EXCEPTION 'Lỗi cập nhật bảng public.school_name: % (Mã lỗi: %)', SQLERRM, SQLSTATE;
END;
$$ LANGUAGE plpgsql VOLATILE STRICT;
`);
},
async down(queryInterface, Sequelize) {
// Hàm down sẽ xóa function này đi khi bạn chạy lệnh db:migrate:undo
// Cần chỉ định rõ kiểu dữ liệu đầu vào (jsonb) để Postgres tìm đúng hàm cần xóa
await queryInterface.sequelize.query(`
DROP FUNCTION IF EXISTS public.update_many_school_names(jsonb);
`);
}
};
Query
- Reload lại Graphile
- Vào groupSchema đã tạo function
- Tìm query many tương tự ví dụ
coreSharedPublicUpdateManySchoolNames
mutation MyMutation($payload: JSON!) {
coreSharedPublicUpdateManySchoolNames(input: {payload: $payload}) {
result {
rowId
name
}
}
}
Variable
- Variables bao gồm object có key "payload" và value là "array"
- Update sẽ dựa vào id để update
{
"payload":[
{"id": 10, "group_id": 3, "name": "Thanh âm của gió v2", "updated_at": "now"},
{"id": 27, "group_id": 3, "name": "Sấm sét của mưa", "updated_at": "now"}
]
}